package com.profgj.profgj.filter;


import com.alibaba.druid.util.StringUtils;
import com.profgj.profgj.config.MyAuthenticationFailureHandler;
import com.profgj.profgj.config.ValidateCodeException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * @Description : 验证码校验过滤器
 * @Author: Liruilong
 * @Date: 2020/2/7 19:39
 */
@Component
public class VerifyCodeFilter extends OncePerRequestFilter {

    /**
     * 创建过滤器对象纳入spring容器中
     * @return
     */
    @Bean
    public VerifyCodeFilter getVerifyCodeFilter() {

        return new VerifyCodeFilter();
    }

    /**
     * 认证失败处理对象
     */
    @Autowired
    MyAuthenticationFailureHandler myAuthenticationFailureHandler;

    /**
     * 内部过滤器
     * @param request
     * @param response
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        // 判断uri是否是登录 且 方法是 post
        if (StringUtils.equals("/login", request.getRequestURI())
                && StringUtils.equalsIgnoreCase(request.getMethod(), "post")) {
            // 1. 进行验证码的校验
            try {
                // 验证码为空的时候处理
                String requestCaptcha = request.getParameter("verifycode");
                if (requestCaptcha == null || requestCaptcha.isEmpty()) {
                    // 标志为1的是验证码不存在
                    request.setAttribute("err_code","1");
                    throw new ValidateCodeException("验证码不存在");
                }
                // 从请求中获取session中的验证码
                String code = (String) request.getSession().getAttribute("verifyCode");
                if (StringUtils.isEmpty(code)) {
                    // 如果为空设为验证码过期
                    request.setAttribute("err_code","1");
                    throw new ValidateCodeException("验证码过期！");
                }
                code = code.equals("0.0") ? "0" : code;
                logger.info("开始校验验证码，生成的验证码为：" + code + " ，输入的验证码为：" + requestCaptcha);
                // 验证码不匹配的处理
                if (!StringUtils.equalsIgnoreCase(code, requestCaptcha)) {
                    request.setAttribute("err_code","2");
                    throw new ValidateCodeException("验证码不匹配");
                }
            } catch (AuthenticationException e) {
                // 2. 捕获步骤1中校验出现异常，交给失败处理类进行进行处理
                myAuthenticationFailureHandler.onAuthenticationFailure(request, response, e);
            } finally {
                filterChain.doFilter(request, response);
            }
        } else {
            filterChain.doFilter(request, response);
        }

    }

}